package learn_funcs

import "fmt"

// 命名返回值
// 如果指定了一个返回值，则可以视为在该函数的第一行中定义了该名字的变量。
func LearnFunc1(width int, height int) (area, perimeter int) {
	area = width * height
	perimeter = width + height
	return
	//在上面的函数中，area 和 perimeter 是命名返回值。注意 return 语句没有指定任何返回值。
	//因为在函数声明时已经指定 area 和 perimeter 是返回值，在遇到 return 语句时它们会自动从函数中返回。
	//在 Golang 中，有返回值的函数，无论是命名返回值还是普通形式的返回值，函数中必须包含 return 语句。
}

// 闭包
func LearnFunc2(limit int) func(v int) bool {
	return func(v int) bool {
		// limit 的值会被缓存
		return limit > v
	}
}

// 可变参数列表
func LearnFunc3(a1 string, a2 string, args ...int) []int {
	fmt.Println(len(args))
	return []int{1, 2, 3, 4}
}

// 函数的延迟执行 defer
// defer 执行顺序是前面的后执行
/*
defer用来声明一个延迟函数，把这个函数放入到一个栈上，
当外部的包含方法return之前，返回参数到调用方法之前调用，也可以说是运行到最外层方法体的"}"时调用。我们经常用他来做一些资源的释放，比如关闭io操作
*/
func LearnFunc4() int {
	defer fmt.Println("hello world")
	defer func() {
		fmt.Println("1")
	}()
	defer func() {
		fmt.Println("2")
	}()
	defer func() {
		fmt.Println("3")
	}()
	return 20
}

func LearnFunc5() (a int) {
	a++
	defer func(ar int) {
		// 传入 copy a的值
		ar = ar + 1
		fmt.Println(ar)
	}(a)
	return 10
}

func LearnFunc6() (a int) {
	b := 250
	defer func() {
		a += 10
		fmt.Println(a) // 10
	}()
	return b
}
